
#ifndef SONFORMAT_H
#define SONFORMAT_H

#include <BFont>
#include <BDockLayout>
#include <BHBoxLayout>
#include <BButton>
#include <BTreeWidget>
#include <BSonNode>
#include <BTextFormat>

using namespace BWE;

class SonFormat : public BTextFormat
{
public:
	enum SonType
	{
		SType_None,
		SType_Item,
		SType_Begin,
		SType_End,
		SType_Text,
		SType_Name,
		SType_Value,
		SType_Annotation,
		SType_Max
	};

	struct SonItem : public BThing
	{
		SonItem*		parent = 0;
		SonType			type = SType_None;
		BRect			rect;
		BFontHolder		font;
		BColor			color;
		BRange			range;
		BArray<BHolder<SonItem>> children;
	};
	typedef BHolder<SonItem>		SonItemHolder;
	typedef BArray<SonItemHolder>	SonItemHolderArray;

public:
	SonFormat(const BString& name = BString());
	~SonFormat();

	virtual void styled(const BStyle* style) override;
	virtual void changed(const BString& text) override;

	virtual const BFont* font(int pos) const;
	virtual const BColor* back(int pos) const;
	virtual const BColor* color(int pos) const;

protected:
	void freshStructure();
	BTreeItem* createTreeItem(BSonNode* node);
	int nextWord(BString& word, const BString& text, int& pos);
	BRange trimmedString(BString::const_iterator& begin, BString::const_iterator& end);
	SonItem* insertSonItem(int pos, int count, SonType type, SonItem* parent = 0);

	bool readSonItem(SonItem* item, const BString& sontext, BString::const_iterator& it, int level);

protected:
	void slotAssetChanged(BObject* object, const BValue& value);
	void slotTextEditFramed(BTextEdit* textEdit, const BValue& value);
	void slotStructureButtonToggled(BObject* object, const BValue& value);

private:
	BHolder<BHBoxLayout>	_topLayout;
	BHolder<BDockLayout>	_dockLayout;
	BButton*				_structureButton;
	BTreeWidget*			_treeWidget;
	BTextEdit*				_textEdit;
	const BStyle*			_style;
	BMap<SonType, BColor>	_colorMap;

	bool					_dirty;
	SonItemHolderArray		_topItems;
	BMap<int, SonItem*>		_itemMap;

};

#endif
